<html>
<head><meta charset="utf-8"><title>longjmp rules · project-ffi-unwind · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/index.html">project-ffi-unwind</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html">longjmp rules</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="211560049"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211560049" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211560049">(Sep 28 2020 at 22:45)</a>:</h4>
<p>I was attending the t-lang triage meeting earlier today, which reviewed this project, which I noted included longjmp.<br>
I was wondering if it may be reasonable to adopt the same rules C++ has with longjmp and leave it at that.<br>
The definition in C++ is that if you replace setjmp with try/catch, and longjmp with throw, the throw would execute a non-trivial destructor, the behaviour is undefined. Rust could make a similar requirement with catch_unwind and panic.</p>



<a name="211562620"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211562620" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211562620">(Sep 28 2020 at 23:15)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> Thanks for asking. We have actually already formally defined the notion of non-trivial cleanup, in preparation for our <code>longjmp</code> specification, in the FFI-unwinding RFC: <a href="https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#plain-old-frames">https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#plain-old-frames</a></p>



<a name="211562692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211562692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211562692">(Sep 28 2020 at 23:16)</a>:</h4>
<p>The reason we don't want to simply go ahead and say "<code>longjmp</code> is well defined across POFs" is that it actually inhibits an optimization that we are interested in.</p>



<a name="211562901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211562901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211562901">(Sep 28 2020 at 23:18)</a>:</h4>
<p>I thought it would be pretty easy to find our previous discussion about it, but apparently not... sorry! I've been meaning to write a blog post to kick off our <code>longjmp</code>-related work, so when I do, I'll be sure to dig up the conversation and include that information.</p>



<a name="211563024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211563024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211563024">(Sep 28 2020 at 23:20)</a>:</h4>
<p>The gist, if I remember correctly, was that we want to be able to re-order certain calls, and in some cases the re-ordering would cause UB if the function is canceled (e.g. w/ <code>longjmp</code>) in between the re-ordered calls, even if only POFs are involved.</p>



<a name="211563228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211563228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211563228">(Sep 28 2020 at 23:23)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> , my comment above wouldn't happen to ring any bells, would it?</p>



<a name="211566436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211566436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211566436">(Sep 29 2020 at 00:05)</a>:</h4>
<p>You can search for longjmp in Zulip using the button at the top of the screen.</p>



<a name="211566470"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/211566470" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#211566470">(Sep 29 2020 at 00:05)</a>:</h4>
<p>Maybe you're referring to the "UB to skip destructors" thread on zulip?</p>



<a name="212720412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/212720412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#212720412">(Oct 08 2020 at 17:03)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> you're correct, that's the thread! I was misled by looking at the first few posts in that thread; RalfJ brought up the optimization towards the end of the thread.</p>



<a name="212720515"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/212720515" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#212720515">(Oct 08 2020 at 17:04)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> Here is the prior discussion about the optimization that can be enabled by prohibiting <code>longjmp</code> in some contexts: <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200759346">https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/200759346</a></p>



<a name="212720557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/212720557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#212720557">(Oct 08 2020 at 17:04)</a>:</h4>
<p>The other benefit of having an explicit annotation for cancelable functions is that the compiler can assist with ensuring that an entire stack is cancelable.</p>



<a name="212720603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/212720603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#212720603">(Oct 08 2020 at 17:04)</a>:</h4>
<p>By the way, our biweekly check-in is in half an hour, so feel free to drop in!</p>



<a name="234688340"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234688340" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234688340">(Apr 15 2021 at 14:42)</a>:</h4>
<p>So apparently now that we emit <code>noalias</code> for <code>&amp;mut</code>, LLVM will actually perform the store sinking optimization that gets broken by <code>longjmp</code>: <a href="https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=b0ac7b34a5bdc7c703247b8ab5dd6a9c">https://play.rust-lang.org/?version=nightly&amp;mode=release&amp;edition=2018&amp;gist=b0ac7b34a5bdc7c703247b8ab5dd6a9c</a></p>



<a name="234688518"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234688518" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234688518">(Apr 15 2021 at 14:44)</a>:</h4>
<p>Interestingly, Clang does this too but GCC doesn't: <a href="https://godbolt.org/z/azj3K5zM1">https://godbolt.org/z/azj3K5zM1</a></p>



<a name="234688618"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234688618" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234688618">(Apr 15 2021 at 14:44)</a>:</h4>
<p>(In all of these examples <code>foo</code> is marked as <code>nounwind</code>)</p>



<a name="234718448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234718448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234718448">(Apr 15 2021 at 17:23)</a>:</h4>
<p>That seems like it would be a miscompilation in LLVM, then?</p>



<a name="234718556"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234718556" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234718556">(Apr 15 2021 at 17:24)</a>:</h4>
<p>Since <code>longjmp</code> from <code>foo</code> to a caller of <code>bar</code> would end up having the wrong value in <code>*x</code>?</p>



<a name="234718933"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234718933" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234718933">(Apr 15 2021 at 17:26)</a>:</h4>
<p>I would personally be <em>extremely chuffed</em> if LLVM ends up introducing a new function attribute representing "longjmpable" or "non-longjmpable" that Rust is able to take advantage of</p>



<a name="234759278"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234759278" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234759278">(Apr 15 2021 at 21:44)</a>:</h4>
<p>This only happens with <code>restrict</code>, which almost nobody uses.</p>



<a name="234759755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234759755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234759755">(Apr 15 2021 at 21:49)</a>:</h4>
<p>I <em>think</em> it's a bug in LLVM: the transformation is invalid unless <code>foo</code> is guranteed to return. I think this would require the <code>willreturn</code> attribute, but I'm not 100% sure.</p>



<a name="234764266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234764266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234764266">(Apr 15 2021 at 22:28)</a>:</h4>
<p>Hm...I don't think we can use <code>willreturn</code>, though, if <code>foo</code> is not <code>noexcept</code>. If <code>foo</code> can unwind, I think this optimization would only be correct if the drop-glue (right term?) for <code>bar</code> could restore the correct value for <code>x</code> (by subtracting 1).</p>



<a name="234782108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234782108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234782108">(Apr 16 2021 at 01:51)</a>:</h4>
<p>LLVM only performs this optimization if <code>foo</code> is <code>nounwind</code>. It doesn't touch the drop glue at all.</p>



<a name="234785326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/234785326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#234785326">(Apr 16 2021 at 02:39)</a>:</h4>
<p>Hm. Then yes, <code>willreturn</code> sounds appropriate for enabling this optimization.</p>



<a name="235545254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/longjmp%20rules/near/235545254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/longjmp.20rules.html#235545254">(Apr 21 2021 at 16:57)</a>:</h4>
<p><span class="user-mention" data-user-id="143274">@Amanieu</span> would you mind opening a bug report for this? If you're busy I can do it, but I think you probably understand the details better than I do.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>